package jrain.fw.httpclient.apache;

import java.io.IOException;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import jrain.fw.core.http.HttpClientService;
import jrain.fw.core.http.HttpMethod;
import jrain.fw.core.http.HttpRequest;
import jrain.fw.core.http.HttpResponse;
import jrain.fw.core.log.Logger;
import jrain.fw.core.log.LoggerFactory;
import jrain.fw.core.service.DestroyService;
import jrain.fw.core.service.InitService;
import jrain.fw.core.service.Service;
import jrain.fw.core.service.ServiceConst;
import jrain.fw.core.utils.FwUtils;
import jrain.utils.exception.ServiceException;

@Service(name = "apache", group = ServiceConst.S_HTTP_CLIENT_SERVICE, module = ServiceConst.M_HTTP_CLIENT)
public class HttpClientApacheService implements HttpClientService, InitService, DestroyService {

	private static final Logger logger = LoggerFactory.getLogger("http-client-apache");
	private static final CloseableHttpClient httpclient = HttpClients.createDefault();

	@Override
	public HttpResponse doInvoke(HttpRequest request) {
		if (HttpMethod.GET.equals(request.getMethod())) {
			try {
				HttpGet get = new HttpGet(request.getUrl());
				// 请求头设置
				Set<String> headerKeySet = request.getHeader().keySet();
				for (String key : headerKeySet) {
					String value = request.getHeader(key);
					get.addHeader(key, value);
				}
				// 请求内容设置
				ResponseHandler<HttpResponse> responseHandler = new ResponseHandler<HttpResponse>() {
					public HttpResponse handleResponse(final org.apache.http.HttpResponse response) throws ClientProtocolException, IOException {
						int status = response.getStatusLine().getStatusCode();
						HttpResponse rsData = new HttpResponse();
						rsData.setStatus(status);
						HttpEntity entity = response.getEntity();
						String data = entity != null ? EntityUtils.toString(entity) : "";
						rsData.setData(data);
						return rsData;
					}
				};
				HttpResponse resData = httpclient.execute(get, responseHandler);
				return resData;
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new ServiceException(e.getMessage(), e);
			}
		} else if (HttpMethod.POST.equals(request.getMethod()) || HttpMethod.PUT.equals(request.getMethod()) || HttpMethod.DELETE.equals(request.getMethod())) {
			try {
				HttpPost post = new HttpPost(request.getUrl());
				// 请求头设置
				Set<String> headerKeySet = request.getHeader().keySet();
				for (String key : headerKeySet) {
					String value = request.getHeader(key);
					post.addHeader(key, value);
				}
				// 请求内容设置
				String json = FwUtils.getJsonService().toJson(request.getData());
				post.setEntity(new StringEntity(json));
				// 请求结果处理
				ResponseHandler<HttpResponse> responseHandler = new ResponseHandler<HttpResponse>() {
					public HttpResponse handleResponse(final org.apache.http.HttpResponse response) throws ClientProtocolException, IOException {
						int status = response.getStatusLine().getStatusCode();
						HttpResponse rsData = new HttpResponse();
						rsData.setStatus(status);
						HttpEntity entity = response.getEntity();
						String data = entity != null ? EntityUtils.toString(entity) : "";
						rsData.setData(data);
						return rsData;
					}
				};
				HttpResponse resData = httpclient.execute(post, responseHandler);
				return resData;
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new ServiceException(e.getMessage(), e);
			}
		} else {
			throw new ServiceException("request type not supported,type=" + request.getMethod());
		}

	}

	@Override
	public void init() {
		logger.info("{} apache started!", ServiceConst.S_HTTP_CLIENT_SERVICE);
	}

	@Override
	public void destroy() {
		logger.info("{} apache stoped!", ServiceConst.S_HTTP_CLIENT_SERVICE);
	}

}
